package pl.com.like.sequoia.web.util;

import java.util.Iterator;
import java.util.Map;

import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class JsfUtils {

	private static Logger _log = LoggerFactory.getLogger(JsfUtils.class);

	/**
	 * Add error message.
	 * 
	 * @param msg the error message
	 */
	public static void addErrorMessage(String msg) {
		addErrorMessage(null, msg);
	}

	/**
	 * Add error message to a sepcific client.
	 * 
	 * @param clientId the client id
	 * @param msg the error message
	 */
	public static void addErrorMessage(String clientId, String msg) {
		if (getCurrentInstance() != null && !existsInFaces(msg))
			getCurrentInstance().addMessage(clientId, new FacesMessage(FacesMessage.SEVERITY_ERROR, msg, msg));
	}

	/**
	 * Add error message.
	 * 
	 * @param msg the error message
	 */
	public static void addInfoMessage(String msg) {
		addInfoMessage(null, msg);
	}

	/**
	 * Add error message to a sepcific client.
	 * 
	 * @param clientId the client id
	 * @param msg the error message
	 */
	public static void addInfoMessage(String clientId, String msg) {
		if (getCurrentInstance() != null && !existsInFaces(msg))
			getCurrentInstance().addMessage(clientId, new FacesMessage(FacesMessage.SEVERITY_INFO, msg, msg));
	}

	/**
	 * Add error message.
	 * 
	 * @param msg the error message
	 */
	public static void addWarnMessage(String msg) {
		addWarnMessage(null, msg);
	}

	/**
	 * Add error message to a sepcific client.
	 * 
	 * @param clientId the client id
	 * @param msg the error message
	 */
	public static void addWarnMessage(String clientId, String msg) {
		if (getCurrentInstance() != null && !existsInFaces(msg))
			getCurrentInstance().addMessage(clientId, new FacesMessage(FacesMessage.SEVERITY_WARN, msg, msg));
	}

	/**
	 * Clears all faces messages.
	 */
	public static void clearAllMessages() {
		Iterator<FacesMessage> it = getCurrentInstance().getMessages();
		while (it.hasNext()) {
			it.next();
			it.remove();
		}
	}

	public static boolean existsInFaces(String msg) {
		Iterator<FacesMessage> fmsgs = getCurrentInstance().getMessages();
		while (fmsgs.hasNext()) {
			FacesMessage fmsg = fmsgs.next();
			if (fmsg.getSummary().equals(msg))
				return true;
		}
		return false;
	}

	public static FacesContext getCurrentInstance() {
		return FacesContext.getCurrentInstance();
	}

	/**
	 * Gets the id of the given parameter name.
	 * 
	 * @param parameterName the parameter name
	 * @return the id
	 */
	public static long getId(String parameterName) {
		String valueText = null;
		try {
			valueText = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get(
					parameterName);
			return new Long(valueText);
		} catch (NumberFormatException e) {
			throw new RuntimeException("couldn't parse '" + parameterName + "'='" + valueText + "' as a long");
		}
	}

	public static String getParameter(String name) {
		return FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get(name);
	}

	public static Long getRenderTime(Long startTime) {
		return System.currentTimeMillis() - startTime;
	}

	public static HttpServletRequest getRequest() {
		return (HttpServletRequest) getCurrentInstance().getExternalContext().getRequest();
	}

	/**
	 * Get parameter value from request scope.
	 * 
	 * @param name the name of the parameter
	 * @return the parameter value
	 */
	public static String getRequestParameter(String name) {
		return getCurrentInstance().getExternalContext().getRequestParameterMap().get(name);
	}

	public static HttpServletResponse getResponse() {
		return (HttpServletResponse) getCurrentInstance().getExternalContext().getResponse();
	}

	/**
	 * Get servlet context.
	 * 
	 * @return the servlet context
	 */
	public static ServletContext getServletContext() {
		return (ServletContext) getCurrentInstance().getExternalContext().getContext();
	}

	public static HttpSession getSession() {
		return (HttpSession) getCurrentInstance().getExternalContext().getSession(false);
	}

	public static Object getSessionAttribute(String key) {
		return FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get(key);
	}

	public static void removeSessionAttribute(String key) {
		FacesContext.getCurrentInstance().getExternalContext().getSessionMap().remove(key);
	}

	/**
	 * Store the managed bean inside the session scope.
	 * 
	 * @param beanName the name of the managed bean to be stored
	 * @param managedBean the managed bean to be stored
	 */
	public static void setManagedBeanInSession(String beanName, Object managedBean) {
		// noinspection unchecked
		Map<String, Object> map = getCurrentInstance().getExternalContext().getSessionMap();
		map.put(beanName, managedBean);
	}
}
